﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.IO;
using ICSharpCode.SharpZipLib.Zip;
using DAL.EstRec;
using System.Data;


namespace FileOps
{
    public delegate void EventHandler<FolderSyncEventArgs>(object sender, FolderSyncEventArgs e);

    public class FolderSync
    {
        #region members

        #region--------------- descarga de archivos
        string serverFilesFolder;

        public string ServerFilesFolder
        {
            get { return serverFilesFolder; }
            set { serverFilesFolder = value; }
        }

        string clientFilesFolder;

        public string ClientFilesFolder
        {
            get { return clientFilesFolder; }
            set { clientFilesFolder = value; }
        }

        #endregion


        #region ---------------- sync cat paths
        string clientFileFolder;
        public string ClientFileFolder
        {
            get { return clientFileFolder; }
            set { clientFileFolder = value; }
        }

        string serverFileFolder;
        public string ServerFileFolder
        {
            get { return serverFileFolder; }
            set { serverFileFolder = value; }
        }

        /// <summary>
        /// Carpeta en el servidor para zips de catálogos
        /// </summary>
        string catZipPath;
        public string CatZipPath
        {
            get { return catZipPath; }
            set { catZipPath = value; }
        }

        /// <summary>
        /// Crpeta en el cliente para descomprimir Zips de catálogos
        /// </summary>
        string tmpCatPath;
        public string TmpCatPath
        {
            get { return tmpCatPath; }
            set { tmpCatPath = value; }
        }

        /// <summary>
        ///  carpeta en el cliente para descargar zips de catálogos
        /// </summary>
        string clntCatZipPath;
        public string ClntCatZipPath
        {
            get { return clntCatZipPath; }
            set { clntCatZipPath = value; }
        }

        #endregion

        #region -------------- data paths

        string clientDataPath;
        public string ClientDataPath
        {
            get { return clientDataPath; }
            set { clientDataPath = value; }
        }

        string serverDataPath;
        public string ServerDataPath
        {
            get { return serverDataPath; }
            set { serverDataPath = value; }
        }

        string dataFilesFolder;
        public string DataFilesFolder
        {
            get { return dataFilesFolder; }
            set { dataFilesFolder = value; }
        }

        string filesProcessedPath;
        public string FilesProcessedPath
        {
            get { return filesProcessedPath; }
            set { filesProcessedPath = value; }
        }

        #endregion

        #region propiedades

        string codePosFDV;
        public string CodePosFDV
        {
            get { return codePosFDV; }
            set { codePosFDV = value; }
        }

        string fileName;
        public string FileName
        {
            get { return fileName; }
            set { fileName = value; }
        }

        long unidFile;
        public long UnidFile
        {
            get { return unidFile; }
            set { unidFile = value; }
        }

        bool is_synchronized;
        public bool Is_synchronized
        {
            get { return is_synchronized; }
            set { is_synchronized = value; }
        }

        bool is_uploaded;
        public bool Is_uploaded
        {
            get { return is_uploaded; }
            set { is_uploaded = value; }
        }

        bool has_error;
        public bool Has_error
        {
            get { return has_error; }
            set { has_error = value; }
        }

        #endregion

        public Dictionary<string, string> Result
        {
            get { return result; }
            set { result = value; }
        }

        Dictionary<string, string> result;
        List<string> filesToSync;
        List<string> filesToDelete;

        int err;
        string errorMessage;

        private AttFile fileSync;
        private DataTable fdv;
        DataTable dt;

        private List<Catalogo> catList;

        #endregion

        #region Delegate and Events

        public event EventHandler<FolderSyncEventArgs> SyncCompletedEvent;

        public virtual void OnSyncCompletedEvent(FolderSyncEventArgs e)
        {
            SyncCompletedEvent(this, e);
        }

        // archivo sincronizado
        public event EventHandler<FolderSyncEventArgs> FileEvent;

        public virtual void OnFileSyncEvent(FolderSyncEventArgs e)
        {
            FileEvent(this, e);
        }

        // archivo cargado
        public event EventHandler<FolderSyncEventArgs> FileUploadedEvent;

        public virtual void OnFileUploaded(FolderSyncEventArgs e)
        {
            FileUploadedEvent(this, e);
        }

        // archivo descargado
        public event EventHandler<FolderSyncEventArgs> FileDownloadedEvent;

        public virtual void OnFileDownloaded(FolderSyncEventArgs e)
        {
            FileDownloadedEvent(this, e);
        }

        //archivo eliminado
        public event EventHandler<FolderSyncEventArgs> FileDrooppedEvent;

        public virtual void OnFileDropped(FolderSyncEventArgs e)
        {
            FileDrooppedEvent(this, e);
        }

        // archivo descomprimido
        public event EventHandler<FolderSyncEventArgs> FileUnzippedEvent;

        public virtual void OnFileUnzipped(FolderSyncEventArgs e)
        {
            FileUnzippedEvent(this, e);
        }

        //error
        public event EventHandler<FolderSyncEventArgs> FileErrorEvent;

        public virtual void OnFileError(FolderSyncEventArgs e)
        {
            FileErrorEvent(this, e);
        }

        // sync cat starts
        public event EventHandler<FolderSyncEventArgs> CatStartSyncEvent;

        public virtual void OnCatStartSync(FolderSyncEventArgs e)
        {
            CatStartSyncEvent(this, e);
        }

        // sync cat ends
        public event EventHandler<FolderSyncEventArgs> CatEndSyncEvent;

        public virtual void OnCatEndSync(FolderSyncEventArgs e)
        {
            CatEndSyncEvent(this, e);
        }
        #endregion

        // constructor
        public FolderSync()
        {

            this.is_synchronized = false;
            this.is_uploaded = false;
            this.has_error = false;

            this.result = new Dictionary<string, string>();
            this.result.Add("SyncStatus", "No sincronizado");
            this.result.Add("Error", "");

            fileSync = new AttFile();

            getPosCode();
        }

        private void getPosCode()
        {
            fdv = new DataTable();
            try
            {
                fdv = getFDVInfo();

                if (fdv.Rows.Count > 0)
                {
                    this.codePosFDV = fdv.Rows[0]["PositionCode"].ToString().Trim();
                }

            }
            catch (Exception ex)
            {
                this.codePosFDV = "";
            }
        }

        #region sync Folder's files

        public void SyncFiles()
        {
            int totalFilesToSync = 0;

            fileSync.isJustFile = true;
            fileSync.isData = false;
            fileSync.isCat = false;

            try
            {
                #region get  lists

                List<string> origFiles;
                List<string> destFiles;

                if (String.IsNullOrEmpty(this.serverFilesFolder) || String.IsNullOrEmpty(this.clientFilesFolder))
                    return;

                // get Files List from source folder
                origFiles = new List<string>();
                foreach (string item in Directory.GetFiles(serverFilesFolder))
                {
                    origFiles.Add(item.Split('\\').Last());
                }

                // get Files list from target folder
                destFiles = new List<string>();
                foreach (string item in Directory.GetFiles(clientFilesFolder))
                {
                    destFiles.Add(item.Split('\\').Last());
                }

                #endregion


                #region copy files

                filesToSync = GetDistinctFiles(origFiles, destFiles);


                copyFiles(filesToSync, this.clientFilesFolder, this.serverFileFolder); //, out err, out errorMessage);

                #endregion

                #region delete files
                filesToDelete = GetDistinctFiles(destFiles, origFiles);

                if (filesToDelete != null)
                    if (filesToDelete.Count > 0)
                    {
                        foreach (string fileName in filesToDelete)
                        {
                            try
                            {
                                fileSync.FileName = this.clientFilesFolder + "\\" + fileName;
                                File.Delete(fileSync.FileName);
                                if (!File.Exists(fileSync.FileName))
                                {
                                    fileSync.Descargado = false;
                                    fileSync.Eliminado = true;
                                    fileSync.Cargado = false;
                                    //OnFileSyncEvent(new FolderSyncEventArgs() { FileSync = fileSync });
                                    OnFileDropped(new FolderSyncEventArgs() { FileSync = fileSync });
                                }
                            }
                            catch (Exception dex)
                            {
                                Console.WriteLine(dex.Message);
                                errorMessage += "Delete " + fileName + ":" + dex.Message + "|";
                                err++;

                            }

                        }

                    }
                #endregion

                if (filesToSync != null)
                    totalFilesToSync += filesToSync.Count;
                if (filesToDelete != null)
                    totalFilesToSync += filesToDelete.Count;


                if (err == 0)
                {
                    result["SyncStatus"] = "Sincronización exitosa: " + totalFilesToSync.ToString() + " archivos.";
                    result["Error"] = "";
                }
                else
                {
                    result["SyncStatus"] = "Sincronización con " + err.ToString() + " errores de" + totalFilesToSync;
                    result["Error"] = errorMessage;
                }

            }
            catch (Exception ex)
            {
                throw ex;
            }

        }//


        #endregion


        #region Sync Cat

        public bool SyncCat(bool isOnlyCat)
        {
            if (isOnlyCat)
            {
                fileSync.msg = "Inicia sincronización de catálogos.";
                OnCatStartSync(new FolderSyncEventArgs() { FileSync = fileSync });
            }

            bool done = false;

            List<string> filesArray = new List<string>();
            List<string> catArray = new List<string>();
            List<string> dirArray = new List<string>();

            fileSync.isJustFile = false;
            fileSync.isData = false;
            fileSync.isCat = true;
            fileSync.CntOk = 0;
            fileSync.CntErr = 0;

            try
            {
                #region---------------- Descarga de archivos

                //lista archivos a descargar
                try
                {
                    if (Directory.Exists(this.CatZipPath))
                    {
                        filesArray = Directory.GetFiles(this.CatZipPath).ToList<string>();

                        //  copia archivos en carpeta cliente
                        copyFiles(filesArray, this.clntCatZipPath, catZipPath);

                        filesArray.Clear();
                    }

                }
                catch (Exception exx)
                {
                    fileSync.Error = true;
                    fileSync.Descargado = false;
                    fileSync.msg = exx.Message;
                    fileSync.CntErr++;
                    OnFileError(new FolderSyncEventArgs() { FileSync = fileSync });
                }

                #endregion

                #region ----------- Descomprime zips de catálogos

                //  selecciona los archivos a descomprimir
                filesArray = Directory.GetFiles(this.clntCatZipPath).ToList<string>();

                // descomprime 
                List<string> alreadySyncCats=
                UnzipFiles(filesArray, this.TmpCatPath);


                #endregion

                //lista de directorios donde buscar catálogos
                dirArray = Directory.GetDirectories(this.TmpCatPath).ToList<string>();
                dirArray.Sort();
                //dirArray.Reverse();

                // obtiene info de zips
                this.dt = getCatzipInfo();

                // por cada uno de los zip 
                //foreach (DataRow dr in this.dt.Rows)
                //{
                foreach (string carpeta in dirArray)
                {
                    //DataColumn[] key = new DataColumn() { dt.Columns["UNID_CAT_ZIPFILE"] };
                    //this.dt.PrimaryKey = key;
                    //---------------------------------
                    if (alreadySyncCats.Contains(carpeta.Split('\\').Last().Split('.')[0]))
                    {
                        continue;
                    }

                    //---------------

                    DataRow[] currentFile = this.dt.Select("CAT_ZIPNAME = '" + carpeta.Split('\\').Last().Split('.')[0] + ".zip'");

                    if (currentFile != null)
                        foreach (DataRow r in currentFile)
                        {
                            fileSync.Descargado = bool.Parse(r["IS_DOWNLOADED"].ToString());
                            fileSync.Descomprimido = bool.Parse(r["IS_UNZIPPED"].ToString());
                            fileSync.UnidZip = long.Parse(r["UNID_CAT_ZIPFILE"].ToString());
                            fileSync.IdCat = 0;
                        }

                    //if (!(fileSync.Descargado && fileSync.Descomprimido))
                    if (!(fileSync.Descomprimido))
                    {
                        fileSync.CntOk = 0;
                        continue;
                    }

                    // lista archivos descomprimidos de catálogos
                    catArray = Directory.GetFiles(carpeta).ToList<string>();

                    // ordena catálogos de la carpeta
                    catList = new List<Catalogo>();
                    catArray.ForEach(
                            c => catList.Add(new Catalogo(c))
                        );
                    catList = catList.OrderBy(c => c.orden).ToList();

                    //if (catArray.Count > 0)
                    if (catList.Count > 0)
                    {
                        //foreach (string item in catArray)
                        foreach (Catalogo item in catList)
                        {
                            //----------------- bulk insert                     
                            try
                            {
                                if (doBulkInsert(item.fileFullName, "\\t", false, ""))
                                {
                                    fileSync.msg = "BulkInsert de " + item.fileFullName + " realizado.";
                                    fileSync.FileName = item.fileFullName;
                                    fileSync.Cargado = true;
                                    fileSync.Error = false;
                                    fileSync.CntOk++;
                                    OnFileUploaded(new FolderSyncEventArgs() { FileSync = fileSync });
                                    done = true;
                                }
                            }
                            catch (Exception ex)
                            {
                                fileSync.Error = true;
                                fileSync.FileName = item.fileFullName;
                                fileSync.Cargado = false;
                                fileSync.msg = ex.Message;
                                fileSync.CntErr = 0;
                                OnFileError(new FolderSyncEventArgs() { FileSync = fileSync });
                            }

                        }//foreach

                    }
                    else
                    {
                        fileSync.Error = false;
                        //fileSync.Cargado = false;
                        //fileSync.Descargado
                        fileSync.CntOk = 0;
                        fileSync.msg = "No se encontraron catálogos para actualizar.";
                        OnFileSyncEvent(new FolderSyncEventArgs() { FileSync = fileSync });
                    }



                    //Array.Sort<string>(catArray);

                }// foreach

                //}// foreach zip registrado


            }
            catch (Exception ex)
            {
                fileSync.Error = true;
                fileSync.msg = "Error en la Sincronización de Catálogos: " + ex.Message;
                OnFileError(new FolderSyncEventArgs() { FileSync = fileSync });

                done = false;
            }

            fileSync.isData = false;
            fileSync.isCat = true;
            fileSync.isJustFile = false;

            fileSync.msg = "Sincronización de catálogos finalizada";
            OnFileSyncEvent(new FolderSyncEventArgs() { FileSync = fileSync });


            if (isOnlyCat)
            {
                fileSync.msg = "Finaliza sincronización de catálogos. Errores detectados: " + fileSync.CntErr.ToString();
                OnCatEndSync(new FolderSyncEventArgs() { FileSync = fileSync });
            }

            if (fileSync.CntOk > 0)
            {
                fileSync.msg = "Catálogos sincronizados: " + fileSync.CntOk.ToString() + "/Errores detectados: " + fileSync.CntErr.ToString();
                OnSyncCompletedEvent(new FolderSyncEventArgs() { FileSync = fileSync });
            }

            return done;
        }//

        #endregion


        #region loadData

        public bool loadData()
        {
            bool done = true;

            List<string> filesArray = new List<string>();
            List<string> catArray = new List<string>();
            List<string> dirArray = new List<string>();
            List<string> syncFilesArray = new List<string>();

            fileSync.isJustFile = false;
            fileSync.isData = true;
            fileSync.isCat = false;
            fileSync.CntOk = 0;
            fileSync.CntErr = 0;

            try
            {

                #region---------------- Descarga de archivos

                //lista archivos a descargar
                try
                {
                    filesArray = Directory.GetFiles(this.serverDataPath).ToList<string>();

                    //selecciona los del territorio correspondiente
                    var a = from f
                            in filesArray
                            where f.Split('\\').Last().Split('_')[0] == this.codePosFDV
                            && f.Split('\\').Last().Split('.').Last().ToLower() == "zip"
                            select f;

                    //filesArray.Clear();
                    filesArray = a.ToList<string>();

                    // obtiene los archivos que no están procesados
                    syncFilesArray = GetFilesToSync(filesArray);

                }
                catch (Exception exx)
                {
                    fileSync.Error = true;
                    fileSync.Descargado = false;
                    fileSync.msg = "Descarga de archivos fallida. " + exx.Message;
                    fileSync.CntErr++;
                    OnFileError(new FolderSyncEventArgs() { FileSync = fileSync });
                }
                #endregion

                if (syncFilesArray.Count > 0)
                {
                    //  copia archivos en carpeta cliente
                    copyFiles(syncFilesArray, this.clientDataPath, this.serverDataPath);

                    filesArray.Clear();


                    //  selecciona los archivos a descomprimir
                    filesArray = Directory.GetFiles(this.clientDataPath).ToList<string>();
                    filesArray.Sort();

                    foreach (string file in filesArray)
                    {
                        try
                        {
                            if (uncompressZip(file, this.dataFilesFolder))
                            {
                                string fname = this.dataFilesFolder + file.Split('\\').Last();

                                // BULK INSERT
                                if (doBulkInsert(fname.Split('.')[0] + ".txt", "\\t", false, "STG_ER_HQDATA"))
                                {
                                    fileSync.msg = "BulkInsert de " + fname + " realizado";
                                    fileSync.FileName = fname;
                                    fileSync.Cargado = true;
                                    fileSync.Error = false;
                                    fileSync.isInSTG = true;
                                    OnFileUploaded(new FolderSyncEventArgs() { FileSync = fileSync });

                                    done = true;
                                }//if

                                if (done)
                                {
                                    // LOAD DATA
                                    try
                                    {
                                        if (loadTable("SP_ER_LD_FDV_BGT_VERSION"))
                                        {
                                            fileSync.msg = "Carga de FDV_BGT_VERSION realizada";
                                            fileSync.Cargado = true;
                                            fileSync.Error = false;
                                            fileSync.CntOk++;
                                            OnFileUploaded(new FolderSyncEventArgs() { FileSync = fileSync });
                                        }

                                        if (loadTable("SP_ER_LD_FDV_BGT"))
                                        {
                                            fileSync.msg = "Carga de FDV_BGT realizado";
                                            fileSync.Cargado = true;
                                            fileSync.Error = false;
                                            fileSync.CntOk++;
                                            OnFileUploaded(new FolderSyncEventArgs() { FileSync = fileSync });
                                        }

                                        File.Copy(file, this.filesProcessedPath + fname.Split('\\').Last(), true);
                                        File.Delete(file);
                                    }
                                    catch (Exception exp)
                                    {
                                        if (exp.GetType() == typeof(System.Data.SqlClient.SqlException) && exp.Message.ToLower().Contains("reference constraint"))
                                        {
                                            fileSync.Error = true;
                                            fileSync.Cargado = false;
                                            fileSync.msg = "Es posible que no cuente con los catálogos más reciéntes. No se pudieron actualizar los datos";
                                            fileSync.CntErr++;
                                            OnFileError(new FolderSyncEventArgs() { FileSync = fileSync });
                                        }

                                        fileSync.Error = true;
                                        fileSync.Cargado = false;
                                        fileSync.msg = exp.Message;
                                        fileSync.CntErr++;
                                        OnFileError(new FolderSyncEventArgs() { FileSync = fileSync });
                                    }
                                }// if done
                            }//if
                        }
                        catch (Exception ex)
                        {
                            fileSync.Error = true;
                            fileSync.FileName = file;
                            fileSync.Cargado = false;
                            fileSync.msg = ex.Message;
                            fileSync.CntErr++;
                            OnFileError(new FolderSyncEventArgs() { FileSync = fileSync });
                        }

                    }//foreach


                    fileSync.isData = true;
                    fileSync.isCat = false;
                    fileSync.isJustFile = false;
                    fileSync.msg = "Fin de sincronización de datos.";
                    OnFileSyncEvent(new FolderSyncEventArgs() { FileSync = fileSync });



                    #region -------------- bulkInsert

                    //// lista archivos descomprimidos de datos
                    //catArray = Directory.GetFiles(this.dataFilesFolder).ToList<string>();
                    //catArray.Sort();

                    //if (catArray.Count > 0)
                    //{
                    //    foreach (string item in catArray)
                    //    {
                    //        //----------------- bulk insert                     
                    //        try
                    //        {
                    //            if (doBulkInsert(item, "\\t", false, "STG_ER_HQDATA"))
                    //            {
                    //                fileSync.msg = "BulkInsert de " + item + " realizado";
                    //                fileSync.FileName = item;
                    //                fileSync.Cargado = true;
                    //                fileSync.Error = false;
                    //                fileSync.isInSTG = true;
                    //                OnFileUploaded(new FolderSyncEventArgs() { FileSync = fileSync });

                    //                done = true;
                    //            }
                    //        }
                    //        catch (Exception ex)
                    //        {
                    //            fileSync.Error = true;
                    //            fileSync.FileName = item;
                    //            fileSync.Cargado = false;
                    //            fileSync.msg = ex.Message;
                    //            fileSync.CntErr++;
                    //            OnFileError(new FolderSyncEventArgs() { FileSync = fileSync });
                    //        }

                    //    }//foreach
                    //}
                    #endregion

                    #region --------------- loadData

                    //if (done)
                    //{
                    //    try
                    //    {
                    //        if (loadTable("SP_ER_LD_FDV_BGT_VERSION"))
                    //        {
                    //            //if (this.dt != null)
                    //            //{
                    //            //    DataRow[] r = dt.Select("CAT_ZIPNAME ='" + fileSync.FileName +"'");
                    //            //    fileSync.UnidZip = long.Parse(r[0]["UNID_CAT_ZIPFILE"].ToString());
                    //            //}

                    //            fileSync.msg = "Carga de FDV_BGT_VERSION realizado";
                    //            fileSync.Cargado = true;
                    //            fileSync.Error = false;
                    //            fileSync.CntOk++;
                    //            OnFileUploaded(new FolderSyncEventArgs() { FileSync = fileSync });
                    //        }
                    //    }
                    //    catch (Exception exp)
                    //    {
                    //        fileSync.Error = true;
                    //        fileSync.Cargado = false;
                    //        fileSync.msg = exp.Message;
                    //        fileSync.CntErr++;
                    //        OnFileError(new FolderSyncEventArgs() { FileSync = fileSync });
                    //    }

                    //    try
                    //    {
                    //        if (loadTable("SP_ER_LD_FDV_BGT"))
                    //        {
                    //            fileSync.msg = "Carga de FDV_BGT realizado";
                    //            fileSync.Cargado = true;
                    //            fileSync.Error = false;
                    //            fileSync.CntOk++;
                    //            OnFileUploaded(new FolderSyncEventArgs() { FileSync = fileSync });
                    //        }
                    //    }
                    //    catch (Exception exp)
                    //    {
                    //        fileSync.Error = true;
                    //        fileSync.Cargado = false;
                    //        fileSync.msg = exp.Message;
                    //        fileSync.CntErr++;
                    //        OnFileError(new FolderSyncEventArgs() { FileSync = fileSync });
                    //    }

                    //    fileSync.isData = true;
                    //    fileSync.isCat = false;
                    //    fileSync.isJustFile = false;
                    //    fileSync.msg = "Fin de sincronización de datos.";
                    //    OnFileSyncEvent(new FolderSyncEventArgs() { FileSync = fileSync });
                    //}

                    #endregion
                }
                else
                {

                    fileSync.isData = true;
                    fileSync.isCat = false;
                    fileSync.isJustFile = false;
                    fileSync.msg = "No se encontraron datos para sincronizar.";
                    OnFileSyncEvent(new FolderSyncEventArgs() { FileSync = fileSync });


                }//else (no se encontraron archivos para sincronizar)
            }
            catch (Exception ex)
            {
                fileSync.Error = true;
                fileSync.msg = "Error: " + ex.Message;
                OnFileError(new FolderSyncEventArgs() { FileSync = fileSync });

                done = false;
            }

            if (fileSync.CntOk > 0)
            {
                fileSync.msg = "Datos sincronizados. Errores detectados: " + fileSync.CntErr.ToString();
                OnSyncCompletedEvent(new FolderSyncEventArgs() { FileSync = fileSync });
            }
            return done;

        }//

        #endregion


        private List<string> GetFilesToSync(List<string> origFiles)
        {
            try
            {
                #region get  lists

                //List<string> origFiles;
                List<string> destFiles;

                if (String.IsNullOrEmpty(this.clientDataPath))
                    return null;


                // get Files list from target folder
                destFiles = new List<string>();
                foreach (string item in Directory.GetFiles(this.filesProcessedPath))
                {
                    destFiles.Add(item.Split('\\').Last());
                }

                #endregion


                filesToSync = GetDistinctFiles(origFiles, destFiles);

                return filesToSync;

            }
            catch (Exception ex)
            {
                Console.WriteLine(ex.Message);
                return null;
            }

        }//



        #region generals

        private void copyFiles(List<string> filesToCopy, string targetFolder, string sourceFolder)//,  out int err, out string errorMessage)
        {

            //err = 0;
            //errorMessage = "";

            if (filesToCopy != null)
                if (filesToCopy.Count > 0)
                {
                    foreach (string fileName in filesToCopy)
                    {
                        try
                        {
                            string f = fileName.Split('\\').Last();

                            if (File.Exists(targetFolder + f))// si ya se descargó el catálogo, ya no lo descargará
                                continue;

                            fileSync.FileName = targetFolder + f;
                            File.Copy(sourceFolder + "\\" + f, fileSync.FileName, true);

                            if (File.Exists(fileSync.FileName))
                            {
                                this.fileName = fileName;
                                fileSync.Descargado = true;
                                fileSync.Error = false;
                                fileSync.FileName = fileName;
                                fileSync.msg = fileName + " descargado";
                                //OnFileSyncEvent(new FolderSyncEventArgs() { FileSync = fileSync });
                                OnFileDownloaded(new FolderSyncEventArgs() { FileSync = fileSync });
                            }
                        }
                        catch (Exception dex)
                        {
                            Console.WriteLine(dex.Message);
                            //errorMessage += "Copy " + fileName + ":" + dex.Message + "|";
                            //err++;
                            fileSync.Descargado = false;
                            fileSync.Error = true;
                            fileSync.FileName = fileName;
                            fileSync.msg = "Descarga fallida de " + fileName + ":" + dex.Message + "|";
                            OnFileError(new FolderSyncEventArgs() { FileSync = fileSync });
                        }

                    }

                }
        }// copyfiles

        private List<string> UnzipFiles(List<string> filesArray, string target)
        {
            string newDir = target;
            List<string> alreadySync = new List<string>() ;

            foreach (string item in filesArray)
            {
                if (!File.Exists(item))
                {
                    fileSync.Error = true;
                    fileSync.msg = "No se pueden encontrar " + item + ".";
                    OnFileError(new FolderSyncEventArgs() { FileSync = fileSync });

                    break;
                }

                if (item.Split('.').Last().ToLower() != "zip")
                    continue;

                if (fileSync.isCat)
                {
                    newDir = target + item.Split('\\').Last().Split('.')[0];

                    if (!Directory.Exists(newDir))
                        Directory.CreateDirectory(newDir);
                    else
                    {
                        if (Directory.GetFiles(newDir).ToList().Count >0)
                            alreadySync.Add(item.Split('\\').Last().Split('.')[0]);
                    }
                }

                if (uncompressZip(item, newDir) )
                {
                    Console.WriteLine("archivo descomprimido");
                    fileSync.Error = false;
                    fileSync.msg = "archivo " + item + " descomprimido";
                    fileSync.Descomprimido = true;
                    fileSync.FileName = item;
                    OnFileUnzipped(new FolderSyncEventArgs() { FileSync = fileSync });

                }
                else
                {
                    fileSync.Error = false;
                    fileSync.Descomprimido = false;
                    fileSync.FileName = item;
                    fileSync.msg = "Ya se había descomprimido previamente el archivo " + item;
                    OnFileUnzipped(new FolderSyncEventArgs() { FileSync = fileSync });
                }

            }// foreach
            return alreadySync;
        }

        private List<string> GetDistinctFiles(List<string> list1, List<string> list2)
        {
            List<string> filesList = new List<string>();
            string sourcePath = "";

            try
            {
                // compare lists
                IEnumerable<string> lstNew = null;
                List<string> auxlist = new List<string>();

                if (list1.Count > 0)
                    sourcePath = list1[0].Replace(list1[0].Split('\\').Last(), "");

                list1.ForEach(
                        i => auxlist.Add(i.Split('\\').Last())
                    );

                // Compare two List<string> and display items of lstOne not in lstTwo
                //lstNew = list1.Except(list2);
                lstNew = auxlist.Except(list2);

                filesList = (from l in lstNew
                             where l.Split('\\').Last().Split('.').Last().ToLower() == "zip"
                             select sourcePath + l).ToList<string>();
                //foreach (string item in lstNew)
                //{
                //    filesList.Add(item);
                //}
            }
            catch (Exception ex)
            {
                throw ex;
            }

            return filesList;
        }//



        public static bool uncompressZip(string zipFilePath, string targetFolder)
        {
            bool ret = true;
            try
            {
                if (File.Exists(zipFilePath))
                {
                    string baseDirectory = targetFolder;

                    using (ZipInputStream ZipStream = new ZipInputStream(File.OpenRead(zipFilePath)))
                    {
                        ZipEntry theEntry;
                        while ((theEntry = ZipStream.GetNextEntry()) != null)
                        {
                            if (theEntry.IsFile)
                            {

                                if (theEntry.Name != "")
                                {
                                    string strNewFile = @"" + baseDirectory + @"\" + theEntry.Name;
                                    if (File.Exists(strNewFile))
                                    {
                                        ret = false; 
                                        continue;
                                    }

                                    using (FileStream streamWriter = File.Create(strNewFile))
                                    {

                                        int size = 4096;
                                        byte[] data = new byte[4096];
                                        while (true)
                                        {
                                            size = ZipStream.Read(data, 0, data.Length);
                                            if (size > 0)
                                                streamWriter.Write(data, 0, size);
                                            else
                                                break;
                                        }//while
                                        streamWriter.Close();
                                    }//using
                                }//if
                            }//using
                            else if (theEntry.IsDirectory)
                            {

                                string strNewDirectory = @"" + baseDirectory + @"\" + theEntry.Name;
                                if (!Directory.Exists(strNewDirectory))
                                {
                                    Directory.CreateDirectory(strNewDirectory);
                                }
                            }//else-if
                        }
                        ZipStream.Close();
                    }//using
                }
                else
                {
                    Console.WriteLine("*** El archivo Zip no existe en la carpeta Temporal.");
                }
            }
            catch (Exception ex)
            {
                Console.WriteLine("*** Error al descomprimir: " + ex.Message);
                ret = false;
            }
            return ret;
        }  //////////

        private static bool doBulkInsert(string filename, string delimeter, bool hasHeader, string table)
        {
            bool done = false;
            int result = 0;

            try
            {
                string query = "SP_INITIAL '" + filename + "', '" + delimeter + "'," + hasHeader.ToString();
                query += (!String.IsNullOrEmpty(table)) ? ", '" + table + "'" : "";

                result = SrvDB.ExecuteNonQuery(query);
                done = true;

            }
            catch (Exception ex)
            {
                throw ex;
            }

            return done;
        }//////

        public static DataTable getCatzipInfo()
        {
            //SP_ER_GET_CATZIP_INFO
            bool done = false;
            DataTable result = new DataTable();

            try
            {
                string query = "SP_ER_GET_CATZIP_INFO  ";

                result = SrvDB.ExecuteQuery(query);
                done = true;

            }
            catch (Exception ex)
            {
                throw ex;
            }

            return result;
        }

        public static bool loadTable(string storedProcedure)
        {
            //
            bool done = false;
            int result = 0;

            try
            {
                string query = storedProcedure;

                result = SrvDB.ExecuteNonQuery(query);
                done = true;

            }
            catch (Exception ex)
            {
                throw ex;
            }

            return done;
        }//

        public static DataTable getFDVInfo()
        {
            string query = "SP_ER_GET_FDV_INFO ";
            DataTable dt = new DataTable();

            try
            {
                dt = SrvDB.ExecuteQuery(query);
            }
            catch (Exception ex)
            {
                throw ex;
            }

            return dt;
        }//


        #endregion

    }//end class

    public class AttFile
    {
        public string FileName { get; set; }
        public string msg { get; set; }
        public int IdCat { get; set; }
        public long UnidZip { get; set; }

        public bool isCat { get; set; }
        public bool isData { get; set; }
        public bool isJustFile { get; set; }
        public bool isInSTG { get; set; }

        public bool Descargado { get; set; }
        public bool Eliminado { get; set; }
        public bool Cargado { get; set; }
        public bool Descomprimido { get; set; }
        public bool Error { get; set; }
        public int CntOk { get; set; }
        public int CntErr { get; set; }
    }

    public class FolderSyncEventArgs : EventArgs
    {
        AttFile fileSync;

        public AttFile FileSync
        {
            get { return fileSync; }
            set { fileSync = value; }
        }

        public void fileSyncChange(string name)
        {
            FileSync.FileName = name;
        }


    }//end class
}
